﻿using System;
using System.Collections.Generic;
using System.Linq;
using Pharmacy.Data;
using Pharmacy.Data.Entity;
using System.Transactions;
using Pharmacy.Data.Repositories;
using Pharmacy.Data.Core;
using Pharmacy.Ultilities.Resources;
using Pharmacy.Ultilities;


namespace Pharmacy.Business
{    
    public partial class UnitOfMeasureBO : BaseBusiness
    {
        #region Constructors
        public UnitOfMeasureBO(IObjectContext objectContext) : base(objectContext) { }
        public UnitOfMeasureBO() : base() { }
        #endregion

        #region Public Methods
        public UnitOfMeasure CreateNewUnitOfMeasure(string name, string note)
        {
            UnitOfMeasure newObject;
            using (TransactionScope scope = new TransactionScope())
            {
                // Tạo mới UnitOfMeasure
                newObject = new UnitOfMeasure();
                newObject.Name = name;
                newObject.Note = note;
                newObject.UOMType = (int)Enums.UnitOfMeasureType.COUNT;
                UnitOfMeasureRepository lst = new UnitOfMeasureRepository(PharmacyContext);
                lst.Add(newObject);

                // Tạo mới UnitOfMeasureGroup default
                UnitOfMeasureGroup newObject1 = new UnitOfMeasureGroup() 
                                                    { 
                                                        Code = newObject.Name, 
                                                        Note = newObject.Name, 
                                                        NumberOfDetails = 1 
                                                    };
                //Tạo mới UnitOfMeasureGroupDetail
                UnitOfMeasureGroupDetail newObject2 = new UnitOfMeasureGroupDetail() 
                                                        { 
                                                            SequenceNo = 1, 
                                                            RatePrice = 1, 
                                                            UnitOfMeasure = newObject, 
                                                            UnitOfMeasureGroup = newObject1 
                                                        };
                UnitOfMeasureGroupRepository lstUOMGroup = new UnitOfMeasureGroupRepository(PharmacyContext);
                lstUOMGroup.Add(newObject1);

                PharmacyContext.SaveChanges();
                scope.Complete();
            }
            return newObject;
        }

        public bool EditUnitOfMeasure(int id, string name, string note, out string messageError)
        {
            UnitOfMeasure editObject = null;
            UnitOfMeasureRepository lst = new UnitOfMeasureRepository(PharmacyContext);
            UnitOfMeasureGroupRepository lstUOMGroup = new UnitOfMeasureGroupRepository(PharmacyContext);
            editObject = lst.AsQueryable().First(tmp => tmp.ID == id);
            if (editObject != null)
            {
                messageError = editObject.IsCheckOutByAnotherUser();
                if (messageError.Length == 0)
                {
                    using (TransactionScope scope = new TransactionScope())
                    {
                        try
                        {
                            LockingControl.Lock(editObject);
                            //Chỉnh sửa UnitOfMeasure
                            editObject.Name = name;
                            editObject.Note = note;
                            //Chỉnh sửa UnitOfMeasureGroup default
                            UnitOfMeasureGroup editUOMGroup = lstUOMGroup.AsQueryable().Where(uomGroup => uomGroup.NumberOfDetails == 1
                                                                                            && uomGroup.UnitOfMeasureGroupDetails.Where(uomGD => uomGD.UnitOfMeasure.ID == editObject.ID).Count() > 0)
                                                                                    .First();
                            editUOMGroup.Code = name;
                            editUOMGroup.Note = name;
                                
                            PharmacyContext.SaveChanges();
                            scope.Complete();
                            LockingControl.UnLock(editObject);
                            return true;
                        }
                        catch (PessimisticLockingException ex)
                        {
                            throw new PessimisticLockingException(
                                string.Format(SR.Instance.GetString(Constant.MSG_LOCKBYANOTHERUSER),
                                SR.Instance.GetString(Constant.ENT_UNITOFMEASURE), editObject.Name),
                                ex.LockDataInfo);
                        }
                    }
                }
            }
            else
            {
                messageError = string.Format(SR.Instance.GetString(Constant.KEY_OBJECTISDELETED),
                    Constant.ENT_UNITOFMEASURE);
            }
            return false;
        }

        public bool DeleteUnitOfMeasure(int id, out string messageError)
        {
            UnitOfMeasure deleteObject = null;
            UnitOfMeasureRepository lst = new UnitOfMeasureRepository(PharmacyContext);
            UnitOfMeasureGroupRepository lstUOMGroup = new UnitOfMeasureGroupRepository(PharmacyContext);
            UnitOfMeasureGroupDetailRepository lstUOMGroupDetail = new UnitOfMeasureGroupDetailRepository(PharmacyContext);
            deleteObject = lst.AsQueryable().First(tmp => tmp.ID == id);
            messageError = string.Empty;
            if (deleteObject != null)
            {
                messageError = (LockingControl as PessimisticLocking).IsCheckOutByAnotherUser(deleteObject);
                if (messageError.Length == 0)
                {
                    using (TransactionScope scope = new TransactionScope())
                    {
                        try
                        {
                            LockingControl.Lock(deleteObject);                   
                            // Delete UOMGroup
                            List<UnitOfMeasureGroup> deleteUOMGroup = lstUOMGroup.AsQueryable().Where(uomGroup => uomGroup.UnitOfMeasureGroupDetails.Where(uomGD => uomGD.UnitOfMeasure.ID == deleteObject.ID).Count() > 0)
                                                                                    .ToList();
                            // Delete UOMGroup Detail
                            foreach (UnitOfMeasureGroup uomGroup in deleteUOMGroup)
                            {
                                lstUOMGroupDetail.Delete(uomGroup.UnitOfMeasureGroupDetails.ToList());
                            }
                            lstUOMGroup.Delete(deleteUOMGroup);

                            // Delete UnitOfMeasure
                            lst.Delete(deleteObject);                            
                            PharmacyContext.SaveChanges();
                            scope.Complete();
                            LockingControl.UnLock(deleteObject);
                            return true;
                        }
                        catch (PessimisticLockingException ex)
                        {
                            throw new PessimisticLockingException(
                                string.Format(SR.Instance.GetString(Constant.MSG_LOCKBYANOTHERUSER),
                                SR.Instance.GetString(Constant.ENT_UNITOFMEASURE), deleteObject.Name),
                                ex.LockDataInfo);
                        }
                    }
                }
            }
            else
            {
                messageError = string.Format(SR.Instance.GetString(Constant.KEY_OBJECTISDELETED),
                    Constant.ENT_UNITOFMEASURE);
            }

            return false;
        }
        #endregion
    }
}
